<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Leaflet 滤镜自定义调整工具</title>
    <script src="https://lib.baomitu.com/leaflet/1.9.2/leaflet.js"></script>
    <link rel="stylesheet" href="https://lib.baomitu.com/leaflet/1.9.2/leaflet.css">
    <style>
        * {
            margin: 0;
            padding: 0
        }
        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            cursor: pointer;
        }
        .layer-control {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            padding: 10px;
            border-radius: 4px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            z-index: 1000;
        }
        .filter-control {
            position: absolute;
            top: 10px;
            right: 200px;
            background: white;
            padding: 15px;
            border-radius: 4px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            z-index: 1000;
            width: 300px;
        }
        .filter-control h3 {
            margin-bottom: 15px;
            color: #333;
        }
        .filter-group {
            margin-bottom: 10px;
        }
        .filter-group label {
            display: block;
            margin-bottom: 5px;
            color: #666;
            font-size: 12px;
        }
        .filter-group .input-group {
            display: flex;
            gap: 10px;
            margin-bottom: 5px;
        }
        .filter-group input[type="range"] {
            flex: 1;
        }
        .filter-group .number-input {
            width: 60px;
            padding: 2px 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }
        .filter-group .value {
            font-size: 12px;
            color: #999;
        }
        .copy-button {
            background: #4CAF50;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 10px;
            width: 100%;
        }
        .copy-button:hover {
            background: #45a049;
        }
        .layer-card {
            margin-bottom: 8px;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            display: flex;
            align-items: center;
            background: #f9f9f9;
        }
        .layer-card:hover {
            background: #f0f0f0;
        }
        .layer-card input[type="checkbox"] {
            margin-right: 8px;
        }
        .layer-card label {
            cursor: pointer;
            user-select: none;
        }
        .blueLayer {
            filter: grayscale(100%) invert(100%) sepia(15%) hue-rotate(180deg) saturate(1600%) brightness(70%) contrast(90%);
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <div class="filter-control">
        <h3>滤镜参数调整</h3>
        <div class="filter-group">
            <label><input type="checkbox" id="filter-toggle" checked> 启用滤镜效果</label>
        </div>
        <div class="filter-group">
            <label>灰度 (Grayscale)</label>
            <div class="input-group">
                <input type="range" id="grayscale" min="0" max="100" value="100">
                <input type="number" id="grayscale-input" min="0" max="100" value="100" class="number-input">
            </div>
            <span class="value">100%</span>
        </div>
        <div class="filter-group">
            <label>反相 (Invert)</label>
            <div class="input-group">
                <input type="range" id="invert" min="0" max="100" value="100">
                <input type="number" id="invert-input" min="0" max="100" value="100" class="number-input">
            </div>
            <span class="value">100%</span>
        </div>
        <div class="filter-group">
            <label>深褐色 (Sepia)</label>
            <div class="input-group">
                <input type="range" id="sepia" min="0" max="100" value="15">
                <input type="number" id="sepia-input" min="0" max="100" value="15" class="number-input">
            </div>
            <span class="value">15%</span>
        </div>
        <div class="filter-group">
            <label>色相旋转 (Hue Rotate)</label>
            <div class="input-group">
                <input type="range" id="hue-rotate" min="0" max="360" value="180">
                <input type="number" id="hue-rotate-input" min="0" max="360" value="180" class="number-input">
            </div>
            <span class="value">180deg</span>
        </div>
        <div class="filter-group">
            <label>饱和度 (Saturate)</label>
            <div class="input-group">
                <input type="range" id="saturate" min="0" max="3000" value="1600">
                <input type="number" id="saturate-input" min="0" max="3000" value="1600" class="number-input">
            </div>
            <span class="value">1600%</span>
        </div>
        <div class="filter-group">
            <label>亮度 (Brightness)</label>
            <div class="input-group">
                <input type="range" id="brightness" min="0" max="200" value="70">
                <input type="number" id="brightness-input" min="0" max="200" value="70" class="number-input">
            </div>
            <span class="value">70%</span>
        </div>
        <div class="filter-group">
            <label>对比度 (Contrast)</label>
            <div class="input-group">
                <input type="range" id="contrast" min="0" max="200" value="90">
                <input type="number" id="contrast-input" min="0" max="200" value="90" class="number-input">
            </div>
            <span class="value">90%</span>
        </div>
        <div class="filter-group">
            <label>滤镜样式输入框</label>
            <textarea id="filter-input" placeholder="在此输入或粘贴滤镜样式，例如：filter: grayscale(100%) invert(100%)..." style="width: 100%; height: 60px; margin-bottom: 5px; padding: 5px;"></textarea>
        </div>
        <button class="copy-button" onclick="copyFilterStyle()">复制滤镜样式</button>
    </div>
    <script>
        var crs = L.CRS.EPSG3857;
        var map = L.map("map",{
            crs: crs,
            center:[31.1808, 121.6555],
            zoom:11
        });

        // 高德矢量地图
        var amap_vector = L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
            className:"blueLayer",
            subdomains: ['1', '2', '3', '4'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })
        
        // 高德矢量地图
        var amap_vector_blue = L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
            className:"blueLayer",
            subdomains: ['1', '2', '3', '4'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        // 高德矢量地图（大字号）
        var amap_vector_big_font = L.tileLayer('http://wprd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}', {
            className:"blueLayer",
            subdomains: ['1', '2', '3', '4'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        // 高德影像地图
        var amap_satellite = L.tileLayer('http://wprd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}', {
            className:"blueLayer",
            subdomains: ['1', '2', '3', '4'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })
        
        // 高德注记（配合影像地图一起使用）
        var amap_label = L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}', {
            className:"blueLayer",
            subdomains: ['1', '2', '3', '4'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        // 腾讯矢量地图
        var tencent_satellite = L.tileLayer('https://rt0.map.gtimg.com/tile?z={z}&x={x}&y={-y}&styleid=0&version=256', {
            className:"blueLayer",
            subdomains: ['1', '2', '3'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        // 测试天地图矢量瓦片，需请填写天地图API
        var tiandituToken = '';
        var tianditu_vector = L.tileLayer('https://t{s}.tianditu.gov.cn/vec_w/wmts?service=WMTS&request=GetTile&version=1.0.0&style=default&tilematrixSet=w&format=tiles&width=256&height=256&layer=vec&tilematrix={z}&tilerow={y}&tilecol={x}&tk=' + tiandituToken, {
            className:"blueLayer",
            subdomains: ['0','1', '2', '3','4', '5', '6','7'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        // 天地图注记（配合天地图矢量瓦片一起使用）
        var tianditu_vector_label = L.tileLayer('https://t{s}.tianditu.gov.cn/cva_w/wmts?service=WMTS&request=GetTile&version=1.0.0&style=default&tilematrixSet=w&format=tiles&width=256&height=256&layer=cva&tilematrix={z}&tilerow={y}&tilecol={x}&tk=' + tiandituToken, {
            className:"blueLayer",
            subdomains: ['0','1', '2', '3','4', '5', '6','7'],
            minZoom: 1,
            maxZoom: 22,
            maxNativeZoom: 18,
            zIndex:-1
        })

        map.addLayer(amap_vector);

        // 更新滤镜样式的函数
        function updateFilterStyle(source) {
            const filterEnabled = document.getElementById('filter-toggle').checked;
            const grayscale = document.getElementById(source === 'input' ? 'grayscale-input' : 'grayscale').value;
            const invert = document.getElementById(source === 'input' ? 'invert-input' : 'invert').value;
            const sepia = document.getElementById(source === 'input' ? 'sepia-input' : 'sepia').value;
            const hueRotate = document.getElementById(source === 'input' ? 'hue-rotate-input' : 'hue-rotate').value;
            const saturate = document.getElementById(source === 'input' ? 'saturate-input' : 'saturate').value;
            const brightness = document.getElementById(source === 'input' ? 'brightness-input' : 'brightness').value;
            const contrast = document.getElementById(source === 'input' ? 'contrast-input' : 'contrast').value;

            // 同步滑动条和输入框的值
            if (source === 'input') {
                document.getElementById('grayscale').value = grayscale;
                document.getElementById('invert').value = invert;
                document.getElementById('sepia').value = sepia;
                document.getElementById('hue-rotate').value = hueRotate;
                document.getElementById('saturate').value = saturate;
                document.getElementById('brightness').value = brightness;
                document.getElementById('contrast').value = contrast;
            } else {
                document.getElementById('grayscale-input').value = grayscale;
                document.getElementById('invert-input').value = invert;
                document.getElementById('sepia-input').value = sepia;
                document.getElementById('hue-rotate-input').value = hueRotate;
                document.getElementById('saturate-input').value = saturate;
                document.getElementById('brightness-input').value = brightness;
                document.getElementById('contrast-input').value = contrast;
            }

            const filterStyle = filterEnabled ? `grayscale(${grayscale}%) invert(${invert}%) sepia(${sepia}%) hue-rotate(${hueRotate}deg) saturate(${saturate}%) brightness(${brightness}%) contrast(${contrast}%)` : 'none';
            
            // 更新所有带有blueLayer类的元素的filter样式
            const elements = document.getElementsByClassName('blueLayer');
            for (let element of elements) {
                element.style.filter = filterStyle;
            }

            // 更新显示的值
            document.querySelector('#grayscale + .value').textContent = grayscale + '%';
            document.querySelector('#invert + .value').textContent = invert + '%';
            document.querySelector('#sepia + .value').textContent = sepia + '%';
            document.querySelector('#hue-rotate + .value').textContent = hueRotate + 'deg';
            document.querySelector('#saturate + .value').textContent = saturate + '%';
            document.querySelector('#brightness + .value').textContent = brightness + '%';
            document.querySelector('#contrast + .value').textContent = contrast + '%';
        }

        // 复制滤镜样式的函数
        function copyFilterStyle() {
            const grayscale = document.getElementById('grayscale').value;
            const invert = document.getElementById('invert').value;
            const sepia = document.getElementById('sepia').value;
            const hueRotate = document.getElementById('hue-rotate').value;
            const saturate = document.getElementById('saturate').value;
            const brightness = document.getElementById('brightness').value;
            const contrast = document.getElementById('contrast').value;

            const filterStyle = `filter: grayscale(${grayscale}%) invert(${invert}%) sepia(${sepia}%) hue-rotate(${hueRotate}deg) saturate(${saturate}%) brightness(${brightness}%) contrast(${contrast}%);`;
            
            navigator.clipboard.writeText(filterStyle).then(() => {
                alert('滤镜样式已复制到剪贴板！');
            }).catch(err => {
                console.error('复制失败:', err);
                alert('复制失败，请手动复制。');
            });
        }

        // 为所有滑动条和输入框添加事件监听器
        document.getElementById('grayscale').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('invert').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('sepia').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('hue-rotate').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('saturate').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('brightness').addEventListener('input', () => updateFilterStyle('range'));
        document.getElementById('contrast').addEventListener('input', () => updateFilterStyle('range'));

        document.getElementById('grayscale-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('invert-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('sepia-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('hue-rotate-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('saturate-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('brightness-input').addEventListener('input', () => updateFilterStyle('input'));
        document.getElementById('contrast-input').addEventListener('input', () => updateFilterStyle('input'));

        // 为滤镜开关添加事件监听器
        document.getElementById('filter-toggle').addEventListener('change', () => updateFilterStyle('input'));

        // 解析滤镜样式的函数
        function parseFilterStyle(text) {
            // 移除'filter:'前缀和末尾的分号
            text = text.replace('filter:', '').replace(';', '').trim();
                
                // 解析各个滤镜值
                const parseValue = (filter, unit) => {
                    const match = text.match(new RegExp(`${filter}\\((\\d+)${unit}\\)`));
                    return match ? match[1] : null;
                };

                // 更新各个滤镜值
                const grayscale = parseValue('grayscale', '%');
                const invert = parseValue('invert', '%');
                const sepia = parseValue('sepia', '%');
                const hueRotate = parseValue('hue-rotate', 'deg');
                const saturate = parseValue('saturate', '%');
                const brightness = parseValue('brightness', '%');
                const contrast = parseValue('contrast', '%');

                // 如果成功解析到值，则更新相应的输入框和滑动条
                if (grayscale) document.getElementById('grayscale-input').value = grayscale;
                if (invert) document.getElementById('invert-input').value = invert;
                if (sepia) document.getElementById('sepia-input').value = sepia;
                if (hueRotate) document.getElementById('hue-rotate-input').value = hueRotate;
                if (saturate) document.getElementById('saturate-input').value = saturate;
                if (brightness) document.getElementById('brightness-input').value = brightness;
                if (contrast) document.getElementById('contrast-input').value = contrast;

                // 触发更新以同步所有控件和应用滤镜
                updateFilterStyle('input');
        }

        // 为滤镜样式输入框添加输入事件监听器
        document.getElementById('filter-input').addEventListener('input', function() {
            parseFilterStyle(this.value);
        });

        L.control.scale().addTo(map);
        // showZoomLevel();
        var baseMaps = {
            "高德地图_矢量": amap_vector,
            "高德地图_矢量_大字体": amap_vector_big_font,
            "高德地图_影像": amap_satellite,
            "腾讯地图_矢量": tencent_satellite,
            "天地图_矢量（需填写TK）": tianditu_vector
        };

        var overlayMaps = {
            "高德地图_标注": amap_label,
            "天地图_注记（需填写TK）":tianditu_vector_label
        };

        var layerControl = L.control.layers(baseMaps, overlayMaps).addTo(map);
    </script>
</body>
</html>